package com.fingard.dsp.bank.directbank.baofoo01;

import java.util.HashMap;
import java.util.Map;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * 	宝付单笔代付
 */
public class BaoFoo01SinglePay extends BaoFoo01Base implements ISinglePay {
	/**
	 * 宝付单笔代付
	 */
	public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
		RetAtsSglDetail tmpRetDetail = d_190802(p_req1908);
		
		if(tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)){
			tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
		}
		
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@Override
	public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
		return null;
	}

	//190802对外支付
	private RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception{
		RetAtsSglDetail retDetail = new RetAtsSglDetail();
		
		ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
		if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
			if (actItem == null) {
				throw new Exception("未找到账号" + p_req1908.singleDetail.payAct + "对应的商户配置节点");
			} else {
				throw new Exception("账号" + p_req1908.singleDetail.payAct + "对应的证书文件不存在");
			}
		}
		
		Map<String,String> postParams = new HashMap<String,String>();
		
		postParams.put("member_id", actItem.merchantId);
		postParams.put("terminal_id", actItem.termId);
		postParams.put("data_type", "xml");
        
		XmlTextWriter xmlWriter = new XmlTextWriter();
		xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\" ?>");
		xmlWriter.writeStartElement("trans_content");
		xmlWriter.writeStartElement("trans_reqDatas");
		xmlWriter.writeStartElement("trans_reqData");
		xmlWriter.writeElementString("trans_no", p_req1908.singleDetail.askNumber);
		xmlWriter.writeElementString("trans_money", p_req1908.singleDetail.payAmount);
		xmlWriter.writeElementString("to_acc_name", p_req1908.singleDetail.recName);
		xmlWriter.writeElementString("to_acc_no", p_req1908.singleDetail.recAct);
		xmlWriter.writeElementString("to_bank_name", p_req1908.singleDetail.recBankName);
		xmlWriter.writeElementString("to_pro_name", p_req1908.singleDetail.getOppProvinceAndCity2()[0]);
		xmlWriter.writeElementString("to_city_name", p_req1908.singleDetail.getOppProvinceAndCity2()[1]);
		xmlWriter.writeElementString("to_acc_dept", p_req1908.singleDetail.recBankLocation);
		xmlWriter.writeElementString("trans_card_id", p_req1908.singleDetail.certNum);
		xmlWriter.writeElementString("trans_mobile", p_req1908.singleDetail.cellPhone);
		xmlWriter.writeElementString("trans_summary", "代付");
		xmlWriter.writeEndElement();
		xmlWriter.writeEndDocument();
		
		/**
		 * 加密规则：项目编码UTF-8 
		 * 第一步：BASE64 加密
		 * 第二步：商户私钥加密
		 */
		String base64Str = Base64Encode(xmlWriter.toXmlString());
		String data_content = encryptByPriPfxFile(base64Str,actItem.ownKeyStorePath, actItem.ownKeyPassword);
		
		postParams.put("data_content", data_content);
        postParams.put("version", "4.0.0");
		
		// 请求报文
		WriteBankLogLn("加密数据: " + xmlWriter.toXmlString());
		
		String[] tmpStrRet = sendToBank("withdraw", postParams, actItem);
		
		// 解析银行返回
		if(tmpStrRet[0].length() == 0){
			/**
			 * 在商户终端正常的情况下宝付同步返回会以密文形式返回,如下：
			 * 此时要先宝付提供的公钥解密：RsaCodingUtil.decryptByPubCerFile(reslut, pub_key)
			 * 再次通过BASE64解密：new String(new Base64().decode(reslut))
			 * 在商户终端不正常或宝付代付系统异常的情况下宝付同步返回会以明文形式返回
			 */
			
			if (tmpStrRet[1].contains("trans_content")) {
				//明文返回,报文错误处理
				retDetail.respCode = "-1";
				retDetail.respInfo = "报文参数设置错误";
			}else {
				//密文返回
				//第一步：公钥解密
				String decryptStr = decryptByPubCerFile(tmpStrRet[1], actItem.oppCertFilePath);
				//第二步BASE64解密
				 String  respXml = Base64Decode(decryptStr);
				 
				 WriteBankLogStep3(respXml);
				 
				 StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				
				if(tmpBkReader != null){
					String tmpRespCode = tmpBkReader.getFirstText("/trans_content/trans_head/return_code");
					
					if (tmpRespCode.equals("0000")) {
						retDetail.respCode = "0";
						retDetail.respInfo = tmpBkReader.getFirstText("/trans_content/trans_head/return_msg");
						retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
						retDetail.transAmt = tmpBkReader.getFirstText("/trans_content/trans_reqDatas/trans_reqData/trans_money");
						retDetail.transState = tmpRespCode;
						retDetail.payInfoCode = retDetail.transState;
					}else {
						retDetail.respCode = "-1";
						retDetail.respInfo = tmpBkReader.getFirstText("/trans_content/trans_head/return_msg");
					}
				}else{
					retDetail.respCode = "-1";
					retDetail.respInfo = tmpSbMsg.toString();
				}
			}
		}else if(tmpStrRet[0].equals(ConnState.FAIL)){
			retDetail.respCode = "0";
			retDetail.respInfo = tmpStrRet[1];
			retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
			retDetail.transState = PaymentState.FAIL_Payment;
			retDetail.payInfoCode = tmpStrRet[0];
		}else{
			retDetail.respCode = "-1";
			retDetail.respInfo = tmpStrRet[1];
		}
		return retDetail;
	}

	/**
	 * 宝付单笔代付状态查询
	 */
	public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944)	 throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();
		
		try{
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
				if (actItem == null) {
					throw new Exception("未找到账号" + p_req1944.payAct + "对应的商户配置节点");
				} else {
					throw new Exception("账号" + p_req1944.payAct + "对应的证书文件不存在");
				}
			}
		
			Map<String,String> postParams = new HashMap<String,String>();
			
			postParams.put("member_id", actItem.merchantId);
			postParams.put("terminal_id", actItem.termId);
			postParams.put("data_type", "xml");
	        
			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\""+getCharset()+"\" ?>");
			xmlWriter.writeStartElement("trans_content");
			xmlWriter.writeStartElement("trans_reqDatas");
			xmlWriter.writeStartElement("trans_reqData");
			xmlWriter.writeElementString("trans_batchid", "");
			xmlWriter.writeElementString("trans_no", p_req1944.askNumber);
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			/**
			 * 加密规则：项目编码UTF-8 
			 * 第一步：BASE64 加密
			 * 第二步：商户私钥加密
			 */
			String base64Str = Base64Encode(xmlWriter.toXmlString());
			String data_content = encryptByPriPfxFile(base64Str,actItem.ownKeyStorePath, actItem.ownKeyPassword);
			
			postParams.put("data_content", data_content);
	        postParams.put("version", "4.0.0");
			
			// 请求报文
			WriteBankLogLn("加密数据: " + xmlWriter.toXmlString());
			
			String[] tmpStrRet = sendToBank("withdrawQuery", postParams, actItem);	
			
			// 解析银行返回
			if(tmpStrRet[0].length() == 0){
				/**
				 * 在商户终端正常的情况下宝付同步返回会以密文形式返回,如下：
				 * 此时要先宝付提供的公钥解密：RsaCodingUtil.decryptByPubCerFile(reslut, pub_key)
				 * 再次通过BASE64解密：new String(new Base64().decode(reslut))
				 * 在商户终端不正常或宝付代付系统异常的情况下宝付同步返回会以明文形式返回
				 */
				
				if (tmpStrRet[1].contains("trans_content")) {
					//明文返回,报文错误处理
					tmpRetAtsDetail.respCode = "-1";
					tmpRetAtsDetail.respInfo = "报文参数设置错误";
				}else {
					//密文返回
					//第一步：公钥解密
					String decryptStr = decryptByPubCerFile(tmpStrRet[1], actItem.oppCertFilePath);
					//第二步BASE64解密
					 String  respXml = Base64Decode(decryptStr);
					 
					 WriteBankLogStep3(respXml);
					 
					 StringBuilder tmpSbMsg = new StringBuilder();
						XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
						
						if(tmpBkReader != null){
							String tmpRespCode = tmpBkReader.getFirstText("/trans_content/trans_head/return_code");
							
							if (tmpRespCode.equals("0000")) {
								tmpRetAtsDetail.respCode = "0";
								tmpRetAtsDetail.respInfo = tmpBkReader.getFirstText("/trans_content/trans_head/return_msg");
								tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
								tmpRetAtsDetail.transState = tmpRespCode + "+" +  tmpBkReader.getFirstText("/trans_content/trans_reqDatas/trans_reqData/state");
								tmpRetAtsDetail.payInfoCode = tmpRespCode;
								tmpRetAtsDetail.transAmt = tmpBkReader.getFirstText("/trans_content/trans_reqDatas/trans_reqData/trans_money");
							}else {
								tmpRetAtsDetail.respCode = "-1";
								tmpRetAtsDetail.respInfo = tmpBkReader.getFirstText("/trans_content/trans_head/return_msg");
							}
						}else{
							tmpRetAtsDetail.respCode = "-1";
							tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
						}
				}
			}else{
				tmpRetAtsDetail.respCode = "-1";
				tmpRetAtsDetail.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			tmpRetAtsDetail.respCode = "-1";
			tmpRetAtsDetail.respInfo = e.getMessage();
			e.printStackTrace();
		}
		
		retAts.writeRetDetail(tmpRetAtsDetail);
		return retAts;
	}

	@Override
	public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
		return null;
	}
}
